#include<stdio.h> //hello,word!
#include<math.h>
#include<algorithm>
using namespace std;

int father[50];

struct edge{
	int u;    //该边的其中一个顶点 
	int v;    //该边的另一个顶点 
	int w;    //该边的权重 
};
struct graph{
	struct edge edges[200];   
	int vexs;    //图的顶点个数 
	int arcs;    //图的边个数 
}g;

//找到x顶点的父亲 
int find(int x){
	return x==father[x]?x:find(father[x]);
}

//将a结点作为b结点的孩子 
void merge(int a,int b){
	father[a]=b;
}

bool cmp(edge e1,edge e2){
	return e1.w<e2.w;
}

int Kruskal(){
	int i,k,a,b;
	//每个顶点都是一棵单独的树 
	for(i=1;i<=g.vexs;i++){
		father[i] = i;
	}
	for(k=0;k<g.vexs;k++){
		a = find(g.edges[k].u);
		b = find(g.edges[k].v);
		if(a != b){
			merge(a,b);
			printf("%d %d %d\n",g.edges[k].w,g.edges[k].v,g.edges[k].w);
	    }
	}
	return 0;
}
int main()
{
	int i;
    scanf("%d %d",&g.vexs,&g.arcs);
	for(i=0;i<g.arcs;i++){
	   scanf("%d %d %d",&g.edges[i].u,&g.edges[i].v,&g.edges[i].w);
	}
	sort(g.edges,g.edges+g.arcs,cmp);
	printf("选中的最短路径依次为：\n");
	Kruskal();
	return 0;
}
